package api

import (
	"encoding/json"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"mobile-phone/internal/models/dao"
	"mobile-phone/internal/models/services"
	"mobile-phone/internal/request"
	"mobile-phone/pkg"
	"net/http"
	"time"
)

func Register(c *gin.Context) {
	var req request.Register
	err := c.ShouldBind(&req)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "数据不能为空",
		})
		return
	}
	user := dao.User{
		Name: req.Name,
		Pass: req.Pass,
	}
	err = services.CreateUser(user)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "注册失败",
		})
		return
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "注册成功",
		})
	}
}

func Login(c *gin.Context) {
	var req request.Login
	err := c.ShouldBind(&req)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "数据不能为空",
		})
		return
	}
	user := dao.User{
		Name: req.Name,
		Pass: req.Pass,
	}
	res, err := services.GetUserInfo(req.Name)
	if err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "账号不存在则自动注册",
		})
		err = services.CreateUser(user)
		return
	}
	if res.Pass != req.Pass {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "密码错误",
		})
		return
	}
	CustomClaims := pkg.CustomClaims{
		ID: res.ID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Unix() + 86400,
		},
	}
	token, _ := pkg.NewJWT("2209A").CreateToken(CustomClaims)
	c.JSON(http.StatusOK, gin.H{
		"code": http.StatusOK,
		"msg":  "登录成功",
		"data": token,
	})
}

type Data request.Ws

type connection struct {
	ws   *websocket.Conn
	sc   chan []byte
	data *Data
}

var wu = &websocket.Upgrader{ReadBufferSize: 512,
	WriteBufferSize: 512, CheckOrigin: func(r *http.Request) bool { return true }}

func Wss(w http.ResponseWriter, r *http.Request) {
	ws, err := wu.Upgrade(w, r, nil)
	if err != nil {
		return
	}
	c := &connection{sc: make(chan []byte, 256), ws: ws, data: &Data{}}
	go c.writer()
	c.reader()
	defer func() {
		c.data.Type = "logout"
		user_list = del(user_list, c.data.User)
		c.data.UserList = user_list
		c.data.Content = c.data.User
		_, _ = json.Marshal(c.data)

	}()
}

func (c *connection) writer() {
	for message := range c.sc {
		c.ws.WriteMessage(websocket.TextMessage, message)
	}
	c.ws.Close()
}

var user_list = []string{}

func (c *connection) reader() {
	for {
		_, message, err := c.ws.ReadMessage()
		if err != nil {

			break
		}
		json.Unmarshal(message, &c.data)
		switch c.data.Type {
		case "login":
			c.data.User = c.data.Content
			c.data.From = c.data.User
			user_list = append(user_list, c.data.User)
			c.data.UserList = user_list
			_, _ = json.Marshal(c.data)

		case "user":
			c.data.Type = "user"
			_, _ = json.Marshal(c.data)

		case "logout":
			c.data.Type = "logout"
			user_list = del(user_list, c.data.User)
			_, _ = json.Marshal(c.data)

		default:
			fmt.Print("========default================")
		}
	}
}

func del(slice []string, user string) []string {
	count := len(slice)
	if count == 0 {
		return slice
	}
	if count == 1 && slice[0] == user {
		return []string{}
	}
	var n_slice = []string{}
	for i := range slice {
		if slice[i] == user && i == count {
			return slice[:count]
		} else if slice[i] == user {
			n_slice = append(slice[:i], slice[i+1:]...)
			break
		}
	}
	fmt.Println(n_slice)
	return n_slice
}

func Ws(context *gin.Context) {

}

func List(c *gin.Context) {
	var req request.List
	err := c.ShouldBind(&req)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "数据不能为空",
		})
		return
	}
	list, err := services.UserList(req.Name, req.Page, req.PageSize)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "列表展示失败",
		})
		return
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "列表展示成功",
			"data": list,
		})
	}
}

func Friend(c *gin.Context) {
	var req request.Friend
	err := c.ShouldBind(&req)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "数据不能为空",
		})
		return
	}
	user := dao.Friend{
		Adds: req.Adds,
		Ifs:  req.Ifs,
	}
	err = services.AddFriend(user)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": http.StatusBadRequest,
			"msg":  "添加用户失败",
		})
		return
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "删除好友成功",
		})
	}
}
